package rbm.utiles;

import rbm.modelado.datos.elementos.BlockShapeImpl;
import rbm.modelado.datos.elementos.BoardShapeImpl;
import rbm.modelado.datos.elementos.interfaces.BlockShape;
import rbm.modelado.datos.elementos.interfaces.MazeFloor;
import rbm.modelado.global.interfaces.PuzzleConstants;

public class RollTester implements PuzzleConstants
{

   private static Integer xPos;
   private static Integer yPos;

   private static Integer xDim;
   private static Integer yDim;
   private static Integer zDim;



   public static TesterResults testRoll( MazeFloor puzzleFloor, BlockShape shape, 
      Integer xPos, Integer yPos, Integer dir )
   {

      doDims( shape );

      TesterResults tr;

      switch( dir )
      {
         case UP:
            tr = rollUp( shape, xPos, yPos, puzzleFloor ); break;

         case DOWN:
            tr = rollDown( shape, xPos, yPos, puzzleFloor ); break;

         case LEFT:
            tr = rollLeft( shape, xPos, yPos, puzzleFloor ); break;

         default:
            tr = rollRight( shape, xPos, yPos, puzzleFloor ); break;
      }

      return tr;
   }


   private static void doDims( BlockShape shape )
   {
      xDim = shape.getXDim();
      yDim = shape.getYDim();
      zDim = shape.getZDim();
   }


   private static TesterResults rollRight( BlockShape shape1, Integer xPos, Integer yPos, MazeFloor puzzleFloor )
   {
	   BlockShapeImpl newShape = new BlockShapeImpl(zDim,yDim,xDim);
	   BlockShapeImpl shape = (BlockShapeImpl) shape1;

      for( int z = 0; z < zDim; z++ )
         for( int y = 0; y < yDim; y++ )
            for( int x = 0; x < xDim; x++ )
               if( shape.getContentXYZ(x,y,z) )
               {
                  int newX = z;
                  int newZ = xDim - x - 1;

                  newShape.setContentXYZ(newX,y,newZ,true);
               }

      xPos += xDim;

      return testLegal( newShape, xPos, yPos, puzzleFloor );

   }



   private static TesterResults rollLeft( BlockShape shape1, Integer xPos, Integer yPos, MazeFloor puzzleFloor )
   {
	   BlockShape newShape = new BlockShapeImpl(zDim,yDim,xDim);
	   BlockShapeImpl shape = (BlockShapeImpl) shape1;

      for( Integer z = 0; z < zDim; z++ )
         for( Integer y = 0; y < yDim; y++ )
            for( Integer x = 0; x < xDim; x++ )
               if( shape.getContentXYZ(x,y,z) )
               {
                  Integer newX = zDim - z - 1;
                  Integer newZ = x;
     
                  newShape.setContentXYZ(newX,y,newZ,true);
               }

      xPos -= zDim;

      return testLegal( newShape, xPos, yPos, puzzleFloor );

   }


   private static TesterResults rollDown( BlockShape shape1, Integer xPos, Integer yPos, MazeFloor puzzleFloor )
   {
	   BlockShape newShape = new BlockShapeImpl(zDim,yDim,xDim);
	   BlockShapeImpl shape = (BlockShapeImpl) shape1;

      for( Integer z = 0; z < zDim; z++ )
         for( Integer y = 0; y < yDim; y++ )
            for( Integer x = 0; x < xDim; x++ )
               if(  shape.getContentXYZ(x,y,z) )
               {
                  Integer newY = z;
                  Integer newZ = yDim - y - 1;

                  newShape.setContentXYZ(x,newY,newZ,true);
               }

      yPos += yDim;

      return testLegal( newShape, xPos, yPos, puzzleFloor );
   }


   private static TesterResults rollUp( BlockShape shape1, Integer xPos, Integer yPos, MazeFloor puzzleFloor )
   {
	   BlockShape newShape = new BlockShapeImpl(zDim,yDim,xDim);
	   BlockShapeImpl shape = (BlockShapeImpl) shape1;

      for( Integer z = 0; z < zDim; z++ )
         for( Integer y = 0; y < yDim; y++ )
            for( Integer x = 0; x < xDim; x++ )
               if(  shape.getContentXYZ(x,y,z) )
               {
                  Integer newY = zDim - z - 1;
                  Integer newZ = y;

                  newShape.setContentXYZ(x,newY,newZ,true);
               }

      yPos -= zDim;

      return testLegal( newShape, xPos, yPos, puzzleFloor );

   }


   private static TesterResults testLegal( BlockShape shape1, Integer xPos, Integer yPos, MazeFloor puzzleFloor )
   {
      boolean legal = true;
      BlockShapeImpl shape = (BlockShapeImpl) shape1;
      BoardShapeImpl board = (BoardShapeImpl) puzzleFloor;

      for( Integer x = 0; x < shape.getXDim(); x++ )
         for( Integer y = 0; y < shape.getYDim(); y++ )
            if( x + xPos < 0 || x + xPos >= board.getXDim() ||
                y + yPos < 0 || y + yPos >= board.getYDim() ||
               (shape.getContentXYZ(x, y, 0) && board.getContentXY(x + xPos,y + yPos )) )
            {
               legal = false;
               break;
            }

      return new TesterResults( shape, xPos, yPos, legal );
   }


}